<template>
  <div class="chat-ui">
    <div class="chat-header">
      <a-popover>
        <template #content>
          <div
            v-for="option in models"
            :key="option.value"
            class="model-option"
            @click="selectModel(option.value)"
          >
            <img :src="option.icon" :alt="`${option.label} Icon`" />
            <span>{{ option.label }}</span>
          </div>
        </template>
        <div class="selected-model">
          <span class="model-name">{{ getSelectedModel.label }}</span>
          <img :src="getSelectedModel.icon" alt="模型图标" />
        </div>
      </a-popover>
    </div>
    <!-- 聊天窗口 -->
    <div ref="scrollContainer" class="message-card" @wheel="handleWheel">
      <message-item
        v-if="messages.length > 0"
        v-for="(message, index) in messages"
        :message="message"
        :index="index"
        :isLast="messages.length > 1 && messages.length === index + 1"
        :loading="loading"
      />
    </div>
    <!-- 消息发送区域 -->
    <div class="send-btn">
      <div
        style="
          padding: 6px 8px 8px 16px;
          background-color: #ffffff;
          display: flex;
          align-items: flex-end;
        "
      >
        <div style="width: 100%; display: flex; align-items: flex-end">
          <div style="display: flex; align-items: center">
            <a-upload
              :custom-request="customRequest"
              :show-upload-list="false"
              :max-count="1"
              :beforeUpload="handleFileChange"
            >
              <a-tooltip>
                <template #title>上传文件</template>
                <div style="display: flex; align-items: center">
                  <LinkOutlined class="upload-btn" />
                </div>
              </a-tooltip>
            </a-upload>
          </div>
          <a-textarea
            :disabled="loading"
            class="ant-input"
            v-model:value="input"
            placeholder="输入代码，一键添加注释"
            :auto-size="{ minRows: 4, maxRows: 12 }"
            :bordered="false"
            @keydown.enter="pressEnter"
            autofocus
          />
        </div>
        <img
          v-if="loading === false"
          @click="send"
          src="/icon/send2.svg"
          :class="input.trim().length > 0 ? 'send-icon' : 'send-icon-disable'"
        />
        <div v-else class="stop-icon" @click="stop">
          <img src="/icon/stop.svg" style="width: 20px" />
        </div>
      </div>
    </div>

    <div class="to-bottom-card" v-if="showToBottom" @click="toBottom">
      <img src="/icon/to-bottom.svg" class="to-bottom" />
    </div>
  </div>
</template>

<script setup>
import Http from '@/api/http'
import { isLogin } from '@/stores/user'
import messageItem from '@/views/component/messageItem.vue'
import { LinkOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { computed, onMounted, onUnmounted, ref } from 'vue'

const models = ref([
  {
    label: 'DeepSeek',
    value: 'deepseek-v3-250324',
    icon: '/icon/deepseek.svg'
  },
  {
    label: 'DeepSeek R1',
    value: 'deepseek-r1-250528',
    icon: '/icon/deepseek.svg'
  },
  {
    label: '豆包',
    value: 'doubao-seed-1-6-250615',
    icon: '/icon/doubao.png'
  },
  {
    label: 'Kimi-K2',
    value: 'kimi-k2-250711',
    icon: '/icon/kimi.png'
  },
  {
    label: '智谱 AI',
    value: 'glm-4.5',
    icon: '/icon/chatglm.png'
  },
  {
    label: '文心一言 3.5',
    value: 'ernie-3.5-128k',
    icon: '/icon/ernie-bot.png'
  },
  {
    label: '文心一言 4.5',
    value: 'ernie-4.5-turbo-128k',
    icon: '/icon/ernie-bot.png'
  },
  {
    label: '通义千问',
    value: 'qwen-plus',
    icon: '/icon/tongyi.png'
  },
  {
    label: '通义千问 Max',
    value: 'qwen-max',
    icon: '/icon/tongyi.png'
  }
])
const model = ref('deepseek-v3-250324')
const scrollContainer = ref(null)
const autoRefreshScroll = ref(true)
const showToBottom = ref(false)
const input = ref('')
const messages = ref([])
const loading = ref(false)
const clientId = ref(null)
const sessionId = ref(null)
const toolType = ref(null)
const stopFlag = ref(false)
const file = ref(null)

function customRequest() {
  const formData = new FormData()
  formData.append('file', file.value)
  Http.post('/api/file/readFile', formData)
    .then((res) => {
      fileContent.value = res
    })
    .catch((err) => {
      message.error(err)
    })
}

function handleFileChange(fileData) {
  file.value = fileData
}

const getSelectedModel = computed(() => {
  return models.value.find((m) => m.value === model.value) || {}
})

function selectModel(value) {
  model.value = value
}

function pressEnter(e) {
  if (e && e.keyCode === 13) {
    if (e.shiftKey) {
      return
    }
  }
  e.preventDefault()
  send()
}

/**
 * 生成随机ID
 */
function generateId() {
  const timestamp = Date.now() // 毫秒级时间戳
  const randomNum = Math.floor(Math.random() * 10000) // 0-9999 的随机数
  return `${timestamp}${randomNum}`
}

function send() {
  if (loading.value === true) {
    message.warning('请等待AI回答完后再发送')
    return
  }
  if (input.value.trim().length === 0) {
    return
  }
  messages.value.push({
    id: generateId(),
    role: 'user',
    content: input.value
  })
  const requestParams = {
    modelName: model.value,
    chatId: generateId(),
    clientId: clientId.value,
    sessionId: sessionId.value,
    content: input.value,
  }
  input.value = ''
  stopFlag.value = false
  // 滚动到最底部
  refreshScroll()
  Http.post('/api/chat/stream', requestParams)
    .then((res) => {
      loading.value = true
    })
    .catch((err) => {
      loading.value = false
      stopFlag.value = false
      message.error('系统异常，请联系站长')
    })
}

// 监听滚动事件
function handleWheel(event) {
  if (scrollContainer.value === null) {
    return
  }
  if (event.deltaY > 0) {
    if (
      scrollContainer.value.scrollTop + scrollContainer.value.clientHeight + 100 >=
      scrollContainer.value.scrollHeight
    ) {
      autoRefreshScroll.value = true
      showToBottom.value = false
    }
  } else if (event.deltaY < 0) {
    autoRefreshScroll.value = false
    showToBottom.value = true
  }
}

function refreshScroll() {
  if (scrollContainer.value === null) {
    return
  }
  if (autoRefreshScroll.value === true) {
    scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
  }
}

function toBottom() {
  if (scrollContainer.value === null) {
    return
  }
  scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
  autoRefreshScroll.value = true
  showToBottom.value = false
}

// SSE 实例
let eventSource = null

function stop() {
  stopFlag.value = true
  loading.value = false
}

onMounted(() => {
  if (!isLogin()) {
    return
  }
  sessionId.value = generateId()
  clientId.value = generateId()
  // 使用 URL 参数传递认证信息（如 token）
  const sseUrl = Http.baseUrl + '/sse/event/connect?clientId=' + clientId.value
  eventSource = new EventSource(sseUrl)
  // 监听 message 事件（默认事件）
  eventSource.onmessage = (event) => {
    if (event.data === 'event: stop' || stopFlag.value === true) {
      loading.value = false
      return
    }
    try {
      const data = JSON.parse(event.data)
      if (data.content) {
        const filterMessages = messages.value.find((item) => item.id === data.chatId)
        if (filterMessages) {
          if (toolType.value === 'translation') {
            filterMessages.content = data.content
          } else {
            filterMessages.content += data.content
          }
        } else {
          messages.value.push({
            id: data.chatId,
            role: 'assistant',
            content: data.content
          })
        }

        refreshScroll()
      }
    } catch (err) {
      console.error(err)
    }
  }
  // 监听自定义事件
  eventSource.addEventListener('complete', (event) => {
    loading.value = false
  })
  // 错误处理
  eventSource.onerror = (err) => {
    console.error('SSE error:', err)
    loading.value = false
  }
})

onUnmounted(() => {
  if (eventSource) {
    eventSource.close()
  }
})
</script>

<style scoped>
.chat-ui {
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100vh;
  background-color: #ffffff;
}

.send-btn {
  overflow: hidden;
  border: 1px solid #615ced;
  border-radius: 20px;
  margin: 0 12px 12px 12px;
}

.send-icon {
  width: 34px;
  height: 34px;
  padding: 4px;
  border-radius: 50%;
  background-color: #615ced;
}

.send-icon-disable {
  width: 34px;
  height: 34px;
  padding: 4px;
  border-radius: 50%;
  background-color: #d6d5de;
}

.send-icon:hover {
  cursor: pointer;
  background-color: #807bf4;
}

.send-icon-disable:hover {
  cursor: pointer;
  background-color: #dbdbdf;
}

.ant-input {
  overflow-y: hidden;
}

.ant-input:hover {
  overflow-y: auto;
}

.message-card {
  max-height: calc(100vh - 80px);
  overflow: auto;
  margin: 0 0 12px 10px;
}

.tool-name {
  background: #eeedff;
  color: #615ced;
  padding: 4px 12px;
  border-radius: 16px;
  cursor: pointer;
}

.tool-desc {
  margin-left: 20px;
  color: #a5a5a5;
  font-size: 12px;
}

.stop-icon {
  padding: 4px;
  border-radius: 50%;
  border: 1px solid #d81e06;
  cursor: pointer;
}

.tool-params {
  display: flex;
  align-items: center;
  margin-left: 20px;
}

.to-bottom-card {
  width: 40px;
  padding: 10px;
  border-radius: 50%;
  background: #ffffff;
  position: absolute;
  right: 40%;
  bottom: 120px;
  cursor: pointer;
  transition: 0.3s ease;
}

.to-bottom-card:hover {
  background: #e6e3f6;
}

.to-bottom {
  width: 20px;
}

.chat-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
}

.selected-model {
  width: 160px;
  cursor: pointer;
  padding: 8px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  margin-left: 20px;
}

.selected-model :hover {
  color: #7e5ced;
}

.model-name {
  font-size: 16px;
  font-weight: 600;
}

.selected-model img {
  margin-left: 8px;
  width: 20px;
  height: 20px;
}

.model-option {
  padding: 6px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
}

.model-option:hover {
  border-radius: 6px;
  background-color: #e0dafe;
}

.model-option img {
  margin-right: 8px;
  width: 20px;
  height: 20px;
}

.upload-btn {
  width: 34px;
  height: 34px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid #f5f5f5;
  cursor: pointer;
  background-color: #f5f5f5;
  padding: 4px;
}

.upload-btn :hover {
  color: #1677ff;
}

.file-card {
  max-width: 400px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 6px 24px;
  border: 1px solid #dcdcdc;
  border-radius: 6px;
  margin: 6px 20px;
}

.file-name {
  max-width: 400px;
  color: #000000;
  white-space: nowrap; /* 不换行 */
  overflow: hidden; /* 超出部分隐藏 */
  text-overflow: ellipsis; /* 超出部分显示省略号 */
}

.welcome {
  width: 100%;
  max-height: calc(100vh - 80px);
  overflow: auto;
}

.config-modal :deep(.ant-modal-body) {
  max-height: 60vh;
  overflow-y: auto;
}

.module-title {
  font-weight: 600;
  padding: 12px;
  border-bottom: 1px solid #f5f5f5;
  margin-bottom: 12px;
}

.row {
  height: 40px;
}

.mb-4 {
  margin-bottom: 6px;
}
.mt-4 {
  margin-top: 6px;
}
.mr-2 {
  margin-right: 8px;
}
.flex {
  display: flex;
}
.justify-end {
  justify-content: flex-end;
}
</style>
